package com.funsport.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.funsport.entity.*;
import com.funsport.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户统计数据服务实现
 *
 * @author Fun-Sport Team
 */
@Slf4j
@Service
public class UserStatsServiceImpl implements IUserStatsService {
    
    @Autowired
    private IEventSignupService eventSignupService;
    
    @Autowired
    private IEventService eventService;
    
    @Autowired
    private IPointRecordService pointRecordService;
    
    @Autowired
    private IUserService userService;
    
    @Override
    public Map<String, Object> getDashboardStats(Long userId) {
        Map<String, Object> stats = new HashMap<>();
        
        if (userId == null) {
            // 未登录用户，返回默认值
            stats.put("monthlyEvents", 0);
            stats.put("monthlyEventsChange", 0);
            stats.put("exerciseHours", 0);
            stats.put("exerciseHoursChange", 0);
            stats.put("pointsEarned", 0);
            stats.put("pointsEarnedChange", 0);
            stats.put("friendInteractions", 0);
            stats.put("friendInteractionsChange", 0);
            return stats;
        }
        
        try {
            // 1. 查询本月参与的活动数量
            int monthlyEvents = getMonthlyEventsCount(userId);
            int lastMonthEvents = getLastMonthEventsCount(userId);
            int eventsChange = monthlyEvents - lastMonthEvents;
            stats.put("monthlyEvents", monthlyEvents);
            stats.put("monthlyEventsChange", eventsChange);
            
            // 2. 计算本月运动时长（小时）
            int exerciseHours = getMonthlyExerciseHours(userId);
            int lastMonthHours = getLastMonthExerciseHours(userId);
            int hoursChange = exerciseHours - lastMonthHours;
            stats.put("exerciseHours", exerciseHours);
            stats.put("exerciseHoursChange", hoursChange);
            
            // 3. 查询本月获得的积分
            int pointsEarned = getMonthlyPointsEarned(userId);
            int lastMonthPoints = getLastMonthPointsEarned(userId);
            int pointsChange = pointsEarned - lastMonthPoints;
            stats.put("pointsEarned", pointsEarned);
            stats.put("pointsEarnedChange", pointsChange);
            
            // 4. 查询好友互动数（本月好友数量）
            int friendInteractions = getFriendInteractions(userId);
            int lastMonthInteractions = getLastMonthFriendInteractions(userId);
            int interactionsChange = friendInteractions - lastMonthInteractions;
            stats.put("friendInteractions", friendInteractions);
            stats.put("friendInteractionsChange", interactionsChange);
            
            log.info("获取用户统计数据成功: userId={}, stats={}", userId, stats);
            return stats;
        } catch (Exception e) {
            log.error("获取用户统计数据失败: userId={}", userId, e);
            // 返回默认值
            stats.put("monthlyEvents", 0);
            stats.put("monthlyEventsChange", 0);
            stats.put("exerciseHours", 0);
            stats.put("exerciseHoursChange", 0);
            stats.put("pointsEarned", 0);
            stats.put("pointsEarnedChange", 0);
            stats.put("friendInteractions", 0);
            stats.put("friendInteractionsChange", 0);
            return stats;
        }
    }
    
    @Override
    public Map<String, Object> getUserPoints(Long userId) {
        Map<String, Object> points = new HashMap<>();
        
        if (userId == null) {
            points.put("totalPoints", 0);
            points.put("monthlyEarned", 0);
            points.put("totalEarned", 0);
            points.put("totalUsed", 0);
            return points;
        }
        
        try {
            // 1. 获取当前总积分
            User user = userService.getById(userId);
            int totalPoints = user != null && user.getPoints() != null ? user.getPoints() : 0;
            points.put("totalPoints", totalPoints);
            
            // 2. 获取本月获得积分
            int monthlyEarned = getMonthlyPointsEarned(userId);
            points.put("monthlyEarned", monthlyEarned);
            
            // 3. 获取累计获得积分（所有正值积分记录）
            int totalEarned = getTotalPointsEarned(userId);
            points.put("totalEarned", totalEarned);
            
            // 4. 计算累计使用积分
            int totalUsed = totalEarned - totalPoints;
            points.put("totalUsed", totalUsed > 0 ? totalUsed : 0);
            
            log.info("获取用户积分信息成功: userId={}, points={}", userId, points);
            return points;
        } catch (Exception e) {
            log.error("获取用户积分信息失败: userId={}", userId, e);
            points.put("totalPoints", 0);
            points.put("monthlyEarned", 0);
            points.put("totalEarned", 0);
            points.put("totalUsed", 0);
            return points;
        }
    }
    
    @Override
    public Map<String, Object> getMonthlyEventStats(Long userId) {
        Map<String, Object> monthlyStats = new HashMap<>();
        
        if (userId == null) {
            monthlyStats.put("eventsJoined", 0);
            monthlyStats.put("eventsCreated", 0);
            monthlyStats.put("totalHours", 0);
            monthlyStats.put("pointsEarned", 0);
            return monthlyStats;
        }
        
        try {
            // 1. 本月参与的活动数
            int eventsJoined = getMonthlyEventsCount(userId);
            monthlyStats.put("eventsJoined", eventsJoined);
            
            // 2. 本月创建的活动数
            int eventsCreated = getMonthlyCreatedEventsCount(userId);
            monthlyStats.put("eventsCreated", eventsCreated);
            
            // 3. 本月运动时长
            int totalHours = getMonthlyExerciseHours(userId);
            monthlyStats.put("totalHours", totalHours);
            
            // 4. 本月获得积分
            int pointsEarned = getMonthlyPointsEarned(userId);
            monthlyStats.put("pointsEarned", pointsEarned);
            
            log.info("获取用户本月活动统计成功: userId={}, stats={}", userId, monthlyStats);
            return monthlyStats;
        } catch (Exception e) {
            log.error("获取用户本月活动统计失败: userId={}", userId, e);
            monthlyStats.put("eventsJoined", 0);
            monthlyStats.put("eventsCreated", 0);
            monthlyStats.put("totalHours", 0);
            monthlyStats.put("pointsEarned", 0);
            return monthlyStats;
        }
    }
    
    /**
     * 获取本月参与的活动数量
     */
    private int getMonthlyEventsCount(Long userId) {
        // 获取本月第一天和最后一天
        YearMonth currentMonth = YearMonth.now();
        LocalDateTime monthStart = currentMonth.atDay(1).atStartOfDay();
        LocalDateTime monthEnd = currentMonth.atEndOfMonth().atTime(23, 59, 59);
        
        // 查询本月已确认的活动报名记录
        long count = eventSignupService.count(
            new LambdaQueryWrapper<EventSignup>()
                .eq(EventSignup::getUserId, userId)
                .eq(EventSignup::getStatus, "confirmed")
                .ge(EventSignup::getCreatedAt, monthStart)
                .le(EventSignup::getCreatedAt, monthEnd)
        );
        
        return (int) count;
    }
    
    /**
     * 获取本月创建的活动数量
     */
    private int getMonthlyCreatedEventsCount(Long userId) {
        YearMonth currentMonth = YearMonth.now();
        LocalDateTime monthStart = currentMonth.atDay(1).atStartOfDay();
        LocalDateTime monthEnd = currentMonth.atEndOfMonth().atTime(23, 59, 59);
        
        long count = eventService.count(
            new LambdaQueryWrapper<Event>()
                .eq(Event::getCreatorId, userId)
                .ge(Event::getCreatedAt, monthStart)
                .le(Event::getCreatedAt, monthEnd)
        );
        
        return (int) count;
    }
    
    /**
     * 计算本月运动时长（小时）
     */
    private int getMonthlyExerciseHours(Long userId) {
        // 获取本月第一天和最后一天
        YearMonth currentMonth = YearMonth.now();
        LocalDateTime monthStart = currentMonth.atDay(1).atStartOfDay();
        LocalDateTime monthEnd = currentMonth.atEndOfMonth().atTime(23, 59, 59);
        
        // 查询本月参与且已完成的活动
        List<EventSignup> signups = eventSignupService.list(
            new LambdaQueryWrapper<EventSignup>()
                .eq(EventSignup::getUserId, userId)
                .in(EventSignup::getStatus, "confirmed", "attended")
                .ge(EventSignup::getCreatedAt, monthStart)
                .le(EventSignup::getCreatedAt, monthEnd)
        );
        
        // 计算总时长
        long totalMinutes = 0;
        for (EventSignup signup : signups) {
            Event event = eventService.getById(signup.getEventId());
            if (event != null && event.getStartTime() != null && event.getEndTime() != null) {
                // 只统计已结束的活动
                if (event.getEndTime().isBefore(LocalDateTime.now())) {
                    Duration duration = Duration.between(event.getStartTime(), event.getEndTime());
                    totalMinutes += duration.toMinutes();
                }
            }
        }
        
        // 转换为小时（向上取整）
        return (int) Math.ceil(totalMinutes / 60.0);
    }
    
    /**
     * 获取本月获得的积分
     */
    private int getMonthlyPointsEarned(Long userId) {
        YearMonth currentMonth = YearMonth.now();
        LocalDateTime monthStart = currentMonth.atDay(1).atStartOfDay();
        LocalDateTime monthEnd = currentMonth.atEndOfMonth().atTime(23, 59, 59);
        
        List<PointRecord> records = pointRecordService.list(
            new LambdaQueryWrapper<PointRecord>()
                .eq(PointRecord::getUserId, userId)
                .gt(PointRecord::getPointsChange, 0) // 只统计正值（获得的积分）
                .ge(PointRecord::getCreatedAt, monthStart)
                .le(PointRecord::getCreatedAt, monthEnd)
        );
        
        return records.stream()
            .mapToInt(PointRecord::getPointsChange)
            .sum();
    }
    
    /**
     * 获取累计获得积分
     */
    private int getTotalPointsEarned(Long userId) {
        List<PointRecord> records = pointRecordService.list(
            new LambdaQueryWrapper<PointRecord>()
                .eq(PointRecord::getUserId, userId)
                .gt(PointRecord::getPointsChange, 0) // 只统计正值
        );
        
        return records.stream()
            .mapToInt(PointRecord::getPointsChange)
            .sum();
    }
    
    /**
     * 获取好友互动数
     * 这里简化为返回用户的积分等级作为互动指标
     */
    private int getFriendInteractions(Long userId) {
        try {
            User user = userService.getById(userId);
            // 这里可以根据实际需求调整，比如查询好友数量、评论数、点赞数等
            // 暂时返回用户等级作为一个简单的指标
            return user != null && user.getLevel() != null ? user.getLevel() : 0;
        } catch (Exception e) {
            log.warn("获取好友互动数失败: userId={}", userId, e);
            return 0;
        }
    }
    
    /**
     * 获取上月参与的活动数量
     */
    private int getLastMonthEventsCount(Long userId) {
        // 获取上月第一天和最后一天
        YearMonth lastMonth = YearMonth.now().minusMonths(1);
        LocalDateTime monthStart = lastMonth.atDay(1).atStartOfDay();
        LocalDateTime monthEnd = lastMonth.atEndOfMonth().atTime(23, 59, 59);
        
        // 查询上月已确认的活动报名记录
        long count = eventSignupService.count(
            new LambdaQueryWrapper<EventSignup>()
                .eq(EventSignup::getUserId, userId)
                .eq(EventSignup::getStatus, "confirmed")
                .ge(EventSignup::getCreatedAt, monthStart)
                .le(EventSignup::getCreatedAt, monthEnd)
        );
        
        return (int) count;
    }
    
    /**
     * 计算上月运动时长（小时）
     */
    private int getLastMonthExerciseHours(Long userId) {
        // 获取上月第一天和最后一天
        YearMonth lastMonth = YearMonth.now().minusMonths(1);
        LocalDateTime monthStart = lastMonth.atDay(1).atStartOfDay();
        LocalDateTime monthEnd = lastMonth.atEndOfMonth().atTime(23, 59, 59);
        
        // 查询上月参与且已完成的活动
        List<EventSignup> signups = eventSignupService.list(
            new LambdaQueryWrapper<EventSignup>()
                .eq(EventSignup::getUserId, userId)
                .in(EventSignup::getStatus, "confirmed", "attended")
                .ge(EventSignup::getCreatedAt, monthStart)
                .le(EventSignup::getCreatedAt, monthEnd)
        );
        
        // 计算总时长
        long totalMinutes = 0;
        for (EventSignup signup : signups) {
            Event event = eventService.getById(signup.getEventId());
            if (event != null && event.getStartTime() != null && event.getEndTime() != null) {
                Duration duration = Duration.between(event.getStartTime(), event.getEndTime());
                totalMinutes += duration.toMinutes();
            }
        }
        
        // 转换为小时（向上取整）
        return (int) Math.ceil(totalMinutes / 60.0);
    }
    
    /**
     * 获取上月获得的积分
     */
    private int getLastMonthPointsEarned(Long userId) {
        YearMonth lastMonth = YearMonth.now().minusMonths(1);
        LocalDateTime monthStart = lastMonth.atDay(1).atStartOfDay();
        LocalDateTime monthEnd = lastMonth.atEndOfMonth().atTime(23, 59, 59);
        
        List<PointRecord> records = pointRecordService.list(
            new LambdaQueryWrapper<PointRecord>()
                .eq(PointRecord::getUserId, userId)
                .gt(PointRecord::getPointsChange, 0) // 只统计正值（获得的积分）
                .ge(PointRecord::getCreatedAt, monthStart)
                .le(PointRecord::getCreatedAt, monthEnd)
        );
        
        return records.stream()
            .mapToInt(PointRecord::getPointsChange)
            .sum();
    }
    
    /**
     * 获取上月好友互动数
     */
    private int getLastMonthFriendInteractions(Long userId) {
        // 简化实现：返回0，表示不计算增长
        // 实际应用中可以根据需求实现具体的互动数统计
        return 0;
    }
    
    @Override
    public java.util.List<PointRecord> getPointsRecords(Long userId, String type) {
        if (userId == null) {
            return new java.util.ArrayList<>();
        }
        
        try {
            LambdaQueryWrapper<PointRecord> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PointRecord::getUserId, userId);
            
            // 根据类型筛选
            if ("earned".equals(type)) {
                // 获得积分（正值）
                wrapper.gt(PointRecord::getPointsChange, 0);
            } else if ("used".equals(type)) {
                // 使用积分（负值）
                wrapper.lt(PointRecord::getPointsChange, 0);
            }
            
            // 按创建时间倒序
            wrapper.orderByDesc(PointRecord::getCreatedAt);
            
            // 限制返回100条
            wrapper.last("LIMIT 100");
            
            List<PointRecord> records = pointRecordService.list(wrapper);
            log.info("获取积分记录成功: userId={}, type={}, count={}", userId, type, records.size());
            
            return records;
        } catch (Exception e) {
            log.error("获取积分记录失败: userId={}, type={}", userId, type, e);
            return new java.util.ArrayList<>();
        }
    }
}

